package com.otod.commons.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.otod.base.history.annotation.RecordField;
import com.otod.commons.constants.CommonConstant;

/**
 * Bean工具类
 * @author jqiu
 */
public class BeanUtils extends org.springframework.beans.BeanUtils{
	private final static Logger logger = LoggerFactory.getLogger(BeanUtils.class); 
			
	/**
	 * 比较两个类的修改记录
	 * @param originalObj	原对象
	 * @param editMap		修改Map
	 * @return			[{key:'filedId',name:'filedName',oVal:'xxx',nVal:'xxxx'},{...}...]
	 */
	public static String getModifyInfo(Object originalObj, Map<String,Object> editMap){
		List<RecordField> rfList = new ArrayList<RecordField>();
		List<String> fnList = new ArrayList<String>();				//
		
		Class clazz = originalObj.getClass();
		Field fields[] = clazz.getDeclaredFields();
		for (Field field : fields) {
			if(!field.isAnnotationPresent(RecordField.class)){
				continue;
			}
			RecordField rf = field.getAnnotation(RecordField.class);
			rfList.add(rf);
			
			fnList.add(field.getName());
		}
		
		if(rfList.size()==0){
			return "[]";
		}
		Class<?> oldObjClass = originalObj.getClass();
		Set<String> mapSet = editMap.keySet();
		
		Method[] metheds = oldObjClass.getMethods();
		Object oldValue,newValue;
		
		JSONArray ja = new JSONArray();
		
		RecordField rfTemp;
		for (Method method : metheds) {
			if(!method.getName().startsWith("get")){
				continue;
			}
			String fieldKey = method.getName().substring(3,4).toLowerCase()+ method.getName().substring(4);
			if(!fnList.contains(fieldKey)){
				continue;
			}
			if(!mapSet.contains(fieldKey)){
				continue;
			}
			try {
				oldValue = method.invoke(originalObj);
			} catch (Exception e) {
				logger.error("比较两个类的修改记录发生异常！",e);
				continue;
			}
			
			JSONObject json = new JSONObject();
			
			newValue = editMap.get(fieldKey);

			if(oldValue == null && newValue == null){
				continue;
			}else if(oldValue == null){
				json.put("oVal", "");
				json.put("oId", "");
				json.put("nVal", newValue);
				json.put("nId", newValue);
			}else if(newValue == null){
				json.put("oVal", oldValue);
				json.put("oId", oldValue);
				json.put("nVal", "");
				json.put("nId", "");
			}else{
				String retType = method.getReturnType().getName();
				if(isEqual(retType,oldValue,newValue)){
					continue;
				}
				json.put("oVal", oldValue);
				json.put("oId", oldValue);
				json.put("nVal", newValue);
				json.put("nId", newValue);
			}
			
			rfTemp = rfList.get(fnList.indexOf(fieldKey));
			json.put("key", fieldKey);
			json.put("name", rfTemp.title());
			if(!StringUtils.isEmpty(rfTemp.formart())){
				//情况一：公共下拉时
				if(CommonConstant.HIS_FTTYPE_BIZCODE.equals(rfTemp.formart())){
					json.put("oVal", BizCodeUtil.getBizCodeNameByNo((String)oldValue));
					json.put("nVal", BizCodeUtil.getBizCodeNameByNo((String)newValue));
				}else if(CommonConstant.HIS_FTTYPE_DTAE.equals(rfTemp.formart())){
					json.put("oVal", DateUtils.formatDate((Date)oldValue, "yyyy-MM-dd"));
					json.put("nVal", DateUtils.formatDate((Date)newValue, "yyyy-MM-dd"));
				}else if(CommonConstant.HIS_FTTYPE_DTAETIME.equals(rfTemp.formart())){
					json.put("oVal", DateUtils.formatDate((Date)oldValue, "yyyy-MM-dd HH:mm"));
					json.put("nVal", DateUtils.formatDate((Date)newValue, "yyyy-MM-dd HH:mm"));
				}
			}
			ja.add(json);
		}
		return ja.toJSONString();
	}
	
	/**
	 * 判断值是否相等
	 * @param retType 	字段类型
	 * @param oVal		原值
	 * @param nVal		新值
	 * @return
	 */
	private static boolean isEqual(String retType,Object oVal,Object nVal){
		if(oVal.equals(nVal)){
			return true;
		}
		return false;
	}
	
}
